<template>
  <div class="app-container">
    <el-container style="min-height:700px;height: 100%;">
      <!-- 左侧流程数据模块-->
      <el-card class="box-card" shadow="never" >
        <el-main style="padding: 0">
          <div style='position: relative;'>
            <el-tabs tab-position="top" v-model="activeName" @tab-click="handleClick">
              <!--表单信息-->
              <el-tab-pane name="1">
                <template #label>
                  <span class="custom-tabs-label">
                    <i class="element-icons el-icon-form"></i>
                    <span>表单信息</span>
                  </span>
                </template>
                <el-col :span="16" :offset="4">
                  <div v-for="(form, index) in flowForms" :key="index">
                    <v-form-render v-if="form.formType === 'online'" ref="vFormRef"/>
                    <component v-else :is="form.formContent" ref="vFormRef"/>
                  </div>
                </el-col>
              </el-tab-pane>

              <!--流程流转记录-->
              <el-tab-pane name="2">
                <template #label>
                  <span class="custom-tabs-label">
                    <i class="element-icons el-icon-flow-record"></i>
                    <span>流转记录</span>
                  </span>
                </template>
                <flow-record v-if="flowRecordOpen" :flowRecordList="flowRecordList" />
              </el-tab-pane>
              <!--流程图-->
              <el-tab-pane name="3">
                <template #label>
                  <span class="custom-tabs-label">
                    <i class="element-icons el-icon-flow"></i>
                    <span>流程图</span>
                  </span>
                </template>
                <bpmn-viewer v-if="flowDataOpen" :flowData="flowData" :procInsId="taskForm.procInsId"/>
              </el-tab-pane>
            </el-tabs>
            <el-button style='position: absolute;right:250px;top:5px;' type="warning" size="small" class="custom-button-size" @click="saveDraft">暂 存</el-button>
            <el-button style='position: absolute;right:180px;top:5px;' type="success" size="small" class="custom-button-size" @click="handleOpenDraft">草稿箱</el-button>
            <el-button style='position: absolute;right:120px;top:5px;' size="small" class="custom-button-size" type="info" @click="handlePrint">打印</el-button>
            <el-button style='position: absolute;right:60px;top:5px;' size="small" class="custom-button-size" type="danger" @click="goBack">关闭</el-button>
            <el-tooltip class="item" effect="dark" placement="top">
              <template #content>{{designer ? '收起' : '展开'}}</template>
              <el-button style='position: absolute;right:10px;top:5px;' size="small" class="custom-button-size" :icon="designer ? 'DArrowRight':'DArrowLeft'" @click="togglePanel"/>
            </el-tooltip>
          </div>
        </el-main>
      </el-card>

      <!--右侧流程处理模块-->
      <el-card shadow="never" :style="designer?'width: 50%':'width: 0'">
        <template #header>
          <div class="card-header">
            <el-icon><Stamp /></el-icon> 任务办理
            <el-tag effect="plain" style="margin-left:10px">发起人:{{ taskForm.startUser }}</el-tag>
            <el-tag effect="plain">任务节点:{{ taskForm.taskName }}</el-tag>
          </div>
        </template>
            <el-form
            label-position="top"
            label-width="100px"
            :model="taskForm"
            ref="taskFormRef"
            style="max-width: 460px"
            size="default"
            >
              <el-form-item label="抄送" prop="copyUser">
                <el-button round style="margin-right: 5px;margin-bottom: 5px" size="small" class="custom-button-size" type="primary" icon="Plus" @click="copyUserOpen = true">添加抄送</el-button>
                <el-tag
                    style="margin-right: 5px;"
                    v-for="user in selectCopyUserList"
                    :key="user.userId"
                    closable
                    effect="plain"
                    @close="removeCopy(user)">
                  {{user.nickName}}
                </el-tag>
              </el-form-item>
              <el-form-item label="处理意见" prop="comment"
                            :rules="[{ required: true, message: '请填写处理意见', trigger: 'blur' }]">
                <el-input type="textarea" :rows="3" v-model="taskForm.comment" placeholder="请填写处理意见"/>
              </el-form-item>
              <el-form-item label="操作" required>
                  <template v-if="taskButtonList.length > 0">
                    <el-button class="button-line custom-button-size" v-for="button in taskButtonList" :key="button.id" plain :icon="button.icon" :size="button.size" :type="button.type" v-on:click="handleButtonClick(button.click)">
                      {{ button.label }}
                    </el-button>
                  </template>
                <!--如果设计流程时未配置按钮信息,那么此时给定一个固定的审批按钮,避免流程任务卡在当前任务节点,无法正常运转-->
                  <template v-else>
                      <el-button plain icon="Check" size="small" class="custom-button-size" type="primary" @click="handleComplete">审 批</el-button>
                  </template>
              </el-form-item>
            </el-form>
      </el-card>
    </el-container>

    <!--选择任务接收人-->
    <el-dialog
        title="待办任务"
        v-model="taskSubmitOpen"
        width="55%"
        :close-on-press-escape="false"
        :destroy-on-close="true"
        append-to-body
    >
      <el-form label-position="top" label-width="100px">
        <template v-for="(item, index) in nextAssignList">
          <el-form-item v-if="item.dataType === 'dynamic'" :key="index">
            <template #label>
              <i style="color:red;">*&nbsp; </i> 任务接收 ({{item.nextNodeName}})
            </template>
            <el-button round style="margin-right: 5px;margin-bottom: 5px" size="small" class="custom-button-size" type="primary" icon="Plus" @click="changeNextAssign(item)">选择任务接收</el-button>
            <el-tag
                style="margin-right: 5px;"
                v-for="assign in item.selectAssignList"
                :key="assign.id"
                closable
                @close="removeAssign(assign, item.nextNodeId)">
              {{assign.name}}
            </el-tag>
          </el-form-item>
        </template>
      </el-form>
      <template #footer>
          <span class="dialog-footer">
            <el-button type="info" size="small" class="custom-button-size" @click="taskSubmitOpen = false">取 消</el-button>
            <el-button type="primary" size="small" class="custom-button-size" @click="submitTask">确 定</el-button>
          </span>
      </template>
    </el-dialog>

    <!--选择抄送人-->
    <el-dialog title="选择抄送人" v-model="copyUserOpen" width="60%" :close-on-press-escape="false" :destroy-on-close="true" :show-close="false">
      <flow-users v-if="copyUserOpen" :selectData="taskForm.checkedCopyUser" @handleAssignSelect="copyUserSelect"/>
      <template #footer>
        <span class="dialog-footer">
          <el-button size="small" class="custom-button-size" @click="copyUserOpen = false">取 消</el-button>
          <el-button type="primary" size="small" class="custom-button-size" @click="submitCopySelect">确 定</el-button>
        </span>
      </template>
    </el-dialog>

    <!--选择流程任务接收人-->
    <el-dialog
        title="选择任务接收"
        v-model="completeOpen"
        :width="currentType === 'dept' ? '30%' : '65%'"
        :before-close="cancelAssignSelect"
        :close-on-press-escape="false"
        :destroy-on-close="true"
        append-to-body
    >
      <component v-if="completeOpen" :is="currentComponent" :selectData="selectDataMap[nextNodeId]" @handleAssignSelect="handleAssignSelect"/>
      <template #footer>
        <span class="dialog-footer">
          <el-button size="small" class="custom-button-size" @click="cancelAssignSelect">取 消</el-button>
          <el-button type="primary" size="small" class="custom-button-size" @click="submitSelect">确 定</el-button>
        </span>
      </template>
    </el-dialog>

    <!--退回任务-->
    <el-dialog title="退回任务" v-model="returnFormOpen" width="50%" append-to-body :destroy-on-close="true">
      <el-form :model="returnTaskForm" label-width="100px" ref="returnTaskFormRef">
        <el-form-item label="目标节点" prop="targetKey" :rules="{ required: true, trigger: ['blur', 'change'], message: '退回任务节点不能为空' }">
          <el-select v-model="returnTaskForm.targetKey" placeholder="请选择退回任务节点" ref="returnTargetKeyRef" @focus="handleReturnTaskViewer">
            <el-option
                v-for="item in returnTaskNode"
                :key="item.key"
                :label="item.name"
                :value="item.key"
            >
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item v-if="returnTaskForm.targetKey" label="退回设置" prop="autoSkip" :rules="{ required: true, trigger: 'change', message: '请选择退回审批设置' }">
          <el-radio-group v-model="returnTaskForm.autoSkip">
            <el-radio label="default">
              默认配置
              <el-tooltip content="跟随流程设计时任务节点已选中退回设置选项" placement="top">
                <el-icon><Warning /></el-icon>
              </el-tooltip>
            </el-radio>
            <el-radio label="rest">
              重新审批
              <el-tooltip content="若流程为A->B->C，C退回至A，则C->A->B->C" placement="top">
                <el-icon><Warning /></el-icon>
              </el-tooltip>
            </el-radio>
            <el-radio label="current">
              从当前节点审批
              <el-tooltip content="若流程为A->B->C，C退回至A，则C->A->C" placement="top">
                <el-icon><Warning /></el-icon>
              </el-tooltip>
            </el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="退回意见" prop="comment" :rules="{ required: true, trigger: ['blur', 'change'], message: '退回意见不能为空' }">
          <el-input type="textarea" :rows="3" v-model="returnTaskForm.comment" placeholder="请填写处理意见"></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
            <el-button size="small" class="custom-button-size" @click="returnFormOpen = false">取 消</el-button>
            <el-button size="small" class="custom-button-size" type="primary" @click="returnTaskComplete">确 定</el-button>
        </span>
      </template>
    </el-dialog>

    <!--选择退回任务节点-->
    <el-dialog title="选择退回任务节点" v-model="returnViewerOpen" width="70%" append-to-body :destroy-on-close="true">
      <div class="el-dialog-div">
        <back-viewer v-if="returnViewerOpen" :flowData="flowNodeData" @handleReturnTaskSelect="returnTaskSelect"/>
      </div>
    </el-dialog>


    <!--动态跳转任务-->
    <el-dialog title="动态跳转" v-model="jumpFormOpen" width="50%" append-to-body :destroy-on-close="true">
      <el-form :model="jumpTaskForm" label-width="100px" ref="jumpTaskFormRef">
        <el-form-item label="目标节点" prop="targetKey" :rules="{ required: true, trigger: ['blur', 'change'], message: '跳转目标节点不能为空' }">
          <el-select v-model="jumpTaskForm.targetKey" placeholder="请选择跳转目标节点" ref="targetKeyRef" @focus="handleJumpTaskViewer">
            <el-option
              v-for="item in jumpTaskNode"
              :key="item.key"
              :label="item.name"
              :value="item.key"
          >
          </el-option>
          </el-select>
        </el-form-item>
        <template v-for="(item, index) in jumpTaskAssignList">
          <el-form-item v-if="item.dataType === 'dynamic'" :key="index">
            <template #label>
              <i style="color:red;">*&nbsp; </i> 任务接收
            </template>
            <el-button round style="margin-right: 5px;margin-bottom: 5px" size="small" class="custom-button-size" type="primary" icon="Plus" @click="changeNextAssign(item)">选择任务接收</el-button>
            <el-tag
                style="margin-right: 5px;"
                v-for="assign in item.selectAssignList"
                :key="assign.id"
                closable
                size="small"
                @close="removeJumpTaskAssign(assign, item.nextNodeId)">
              {{assign.name}}
            </el-tag>
          </el-form-item>
        </template>
        <el-form-item label="处理意见" prop="comment" :rules="{ required: true, trigger: ['blur', 'change'], message: '处理意见不能为空' }">
          <el-input type="textarea" :rows="3" v-model="jumpTaskForm.comment" placeholder="请填写处理意见"></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
            <el-button size="small" class="custom-button-size" @click="jumpFormOpen = false">取 消</el-button>
            <el-button size="small" class="custom-button-size" type="primary" @click="jumpTaskComplete">确 定</el-button>
        </span>
      </template>
    </el-dialog>

    <el-dialog title="选择跳转目标节点" v-model="jumpViewerOpen" width="70%" append-to-body :destroy-on-close="true">
      <div class="el-dialog-div">
        <jump-viewer v-if="jumpViewerOpen" :flowData="flowNodeData" @handleJumpTaskSelect="jumpTaskSelect"/>
      </div>
    </el-dialog>

    <!--委托任务-->
    <el-dialog :title="delegateTaskTitle" v-model="delegateTaskOpen" width="60%" append-to-body>
      <flow-assignee v-if="delegateTaskOpen" :userType="'delegate'" @handleDelegateUser="delegateUserSelect"></flow-assignee>
      <template #footer>
        <span class="dialog-footer">
          <el-button size="small" class="custom-button-size" @click="delegateTaskOpen = false">取 消</el-button>
          <el-button type="primary" size="small" class="custom-button-size" @click="delegateTaskComplete">确 定</el-button>
        </span>
      </template>
    </el-dialog>

    <!--转办任务-->
    <el-dialog :title="transferTaskTitle" v-model="transferTaskOpen" width="60%" append-to-body>
      <flow-assignee v-if="transferTaskOpen" :userType="'transfer'" @handleTransferUser="transferUserSelect"/>
      <template #footer>
        <span class="dialog-footer">
          <el-button size="small" class="custom-button-size" @click="transferTaskOpen = false">取 消</el-button>
          <el-button type="primary" size="small" class="custom-button-size" @click="transferTaskComplete">确 定</el-button>
        </span>
      </template>
    </el-dialog>

    <!--打印预览-->
    <el-dialog
        v-model="printVisible"
        title="打印预览"
        width="70%"
        append-to-body
    >
      <printer v-if="printVisible" :printData="printData"/>
    </el-dialog>

    <!--草稿信息-->
    <el-drawer
        title="草稿信息"
        size="47%"
        v-model="draftOpen"
        :close-on-press-escape="false"
        :destroy-on-close="true"
        direction="rtl"
        append-to-body
    >
      <el-table v-loading="loading" :data="flowDraftList">
        <el-table-column label="主键" align="center" prop="id" />
        <el-table-column label="草稿名称" align="center" prop="draftName" />
        <el-table-column label="创建时间" align="center" prop="createTime" />
        <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
          <template #default="scope">
            <el-button
                link
                size="small"
                type="primary"
                icon="Promotion"
                @click="handleUseDraft(scope.row)"
            >使用</el-button>
            <el-button
                link
                size="small"
                type="danger"
                icon="Delete"
                @click="handleDeleteDraft(scope.row)"
            >删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <pagination
          layout="prev, pager, next"
          v-show="total>0"
          :total="total"
          v-model:page="queryParams.pageNum"
          v-model:limit="queryParams.pageSize"
          @pagination="getDraftList"
      />
    </el-drawer>
  </div>
</template>

<script setup name="TodoDetail">
import {getRecordList} from "@/api/flowable/finished";
import FlowAssignee from '@/components/Flow/Task/Assignee';
import FlowUsers from '@/components/Flow/Task/User';
import BpmnViewer from '@/components/Process/viewer';
import BackViewer from '@/components/Process/nodeViewer/backViewer';
import JumpViewer from "@/components/Process/nodeViewer/jumpViewer";
import Printer from '@/components/Process/printer';
import FlowRecord from "@/components/Process/record";

import {flowXmlAndNode} from "@/api/flowable/definition";
import {
  completeTask,
  rejectTask,
  returnList,
  returnTask,
  getNextFlowNode,
  delegateTask,
  transferTask,
  flowTaskForm,
  flowTaskButton,
  dynamicJumpTask,
  dynamicJump
} from "@/api/flowable/todo";
import {StrUtil} from "@/utils/StrUtil";
import {stopTask, draftList, saveDraftByTask, delDraft} from "@/api/flowable/process";
import {assignSelect, setAssignComponentValue} from "@/views/flowable/common/AssignUtils";

const route = useRoute();
const { proxy } = getCurrentInstance();

// 模型xml数据
const flowData = ref({});
// 按钮列表
const taskButtonList = ref([]);
// 切换tab标签
const activeName = ref('1');
const flowRecordOpen = ref(false);
const flowDataOpen = ref(false);

// 流程流转数据
const flowRecordList = ref([]);
// 审核弹框
const completeOpen = ref(false);
// 退回弹窗
const returnFormOpen = ref(false);
const returnViewerOpen = ref(false);
const returnTaskNode = ref([]);

const selectDataList = ref([]);
const selectCopyDataList = ref([]);
// 表单json
const formJson = ref({});
// 表单渲染器
const vFormRef = ref(null);
// 委托任务
const delegateTaskTitle = ref(null);
const delegateTaskOpen = ref(false);

// 转办任务
const transferTaskTitle = ref(null);
const transferTaskOpen = ref(false);

// 打印预览
const printVisible = ref(false);
const designer = ref(true);

// 抄送人
const copyUserOpen = ref(false);
const selectCopyUserList = ref([]);

// 表单内容
const flowForms = ref([]);

// 用于确定当前显示的组件
const currentType = ref("");
const currentComponent = shallowRef(null);
// 下一节点ID
const nextNodeId = ref('');
const delegationState = ref('');
const taskSubmitOpen = ref(false);

// 动态跳转
const jumpFormOpen = ref(false);
const jumpViewerOpen = ref(false);
const flowNodeData = ref({});
const jumpTaskAssignList = ref([]);
const jumpTaskNode = ref([]);

// 草稿箱
const flowDraftList = ref([]);
const loading = ref(false);
const total = ref(0);
const draftOpen = ref(false);

const data = reactive({
  // 查询参数
  queryParams: {
    pageNum: 1,
    pageSize: 10,
  },
  taskForm: {
    taskName: "", // 任务节点
    startUser: "", //发起人信息
    comment: "", // 意见内容
    procInsId: "", // 流程实例编号
    instanceId: "", // 流程实例编号
    deployId: "",  // 流程定义编号
    taskId: "",// 流程任务编号
    procDefId: "",  // 流程编号
    targetKey: "",
    currentKey: "",
    flowParam: "", // 流程变量参数
    checkedAssignMap: {},
    variables: {},
    formData: {}  // 表单内容
  },
  returnTaskForm: {},
  printData:{},
  nextAssignList: [], // 后续审批
  selectDataMap: {}, // 选中的审批人
  jumpTaskForm: {
    taskName: "", // 任务节点
    startUser: "", //发起人信息
    comment: "", // 意见内容
    procInsId: "", // 流程实例编号
    deployId: "",  // 流程定义编号
    taskId: "",// 流程任务编号
    procDefId: "",  // 流程编号
    targetKey: "", // 目标节点
    currentKey: "", // 当前节点
    flowParam: "", // 流程变量参数
    variables: {}, // 流程变量
    checkedAssignMap: {}, // 选择审批人信息
    formData:{} // 表单内容
  }
});

const {queryParams, taskForm, returnTaskForm, printData, nextAssignList, selectDataMap, jumpTaskForm} = toRefs(data);

if (route.query) {
  taskForm.value = route.query;
  taskForm.value.checkedAssignMap = {};
  getFlowTaskForm();
  getFlowTaskButton();
  printData.value.procInsId = taskForm.value.procInsId;
}


/** tab点击 */
function handleClick(tab, event) {
  if (tab.props.name === '2') {
    // 切换tab时避免重复请求接口
    if (!flowRecordOpen.value) {
      getFlowRecordList();
    }
  }else if (tab.props.name === '3') {
    if (!flowDataOpen.value) {
      flowDataOpen.value = true;
      flowXmlAndNode(taskForm.value).then(res => {
        flowData.value = res.data;
      })
    }
  }
}

/** 隐藏面板*/
function togglePanel() {
  designer.value = !designer.value;
}

/** 获取流程流转记录 */
function getFlowRecordList() {
  // 调用流程记录接口
  getRecordList(taskForm.value).then(res => {
    // 将流程记录列表存入流程记录列表变量中
    flowRecordList.value = res.data.flowList;
    flowRecordOpen.value = true;
  })
}

/** 获取流程节点表单 */
function getFlowTaskForm() {
  if (taskForm.value.taskId) {
    flowTaskForm(taskForm.value).then(res => {
      processFlowForms(res.data);
    });
  }
}

// 处理流程节点表单
function processFlowForms(data) {
  //  保存打印数据
  printData.value.flowForms = data.flowForms;
  printData.value.formData = data.flowData;
  flowForms.value = data.flowForms;

  proxy.$nextTick(() => {
    flowForms.value?.forEach((form, index) => {
      processForm(form, index, data.flowData);
    });
  });
}

// 处理流程节点表单
function processForm(form, index, flowData) {
  if (vFormRef.value) {
    const formRef = vFormRef.value[index];
    if (form.formType === "online") {
      processOnlineForm(formRef, form, flowData);
    } else {
      processRouteForm(formRef, form, flowData);
    }
  }
}

// 处理在线表单
function processOnlineForm(vFormRef, form, flowData) {
  vFormRef.setFormJson(form.formContent);
  vFormRef.setFormData(flowData);
  processWidgets(vFormRef, form.formWidgets);
}

// 处理路由表单
function processRouteForm(vFormRef, form, flowData) {
  vFormRef.setFormData(flowData, false);
  processWidgets(vFormRef, form.formWidgets);
}

// 处理表单组件
function processWidgets(vFormRef, formWidgets) {
  const widgets = JSON.parse(formWidgets);
  const widgetMap = {
    readonly: [],
    readwrite: [],
    invisible: []
  };
  widgets?.forEach(widget => {
    widgetMap[widget.type].push(widget.id);
  });
  proxy.$nextTick(() => {
    vFormRef.disableWidgets(widgetMap.readonly);
    vFormRef.enableWidgets(widgetMap.readwrite);
    vFormRef.hideWidgets(widgetMap.invisible);
  });
}

/** 委托任务 */
function handleDelegate() {
  proxy.$refs["taskFormRef"].validate(valid => {
    if (valid) {
      delegateTaskTitle.value = "委托人选择";
      delegateTaskOpen.value = true;
    }
  })
}

/** 提交处理委托任务 */
function delegateTaskComplete() {
  proxy.$refs["taskFormRef"].validate(valid => {
    if (valid) {
      delegateTask(taskForm.value).then(response => {
        proxy.$modal.msgSuccess(response.msg);
        goBack();
      });
      delegateTaskTitle.value = "";
      delegateTaskOpen.value = false;
    }
  });
}

/** 终止任务 */
function handleStop() {
  proxy.$confirm("确认终止当前任务？", "提示", {
    confirmButtonText: "确 认",
    cancelButtonText: "取 消"
  }).then(() => {
    stopTask(taskForm.value).then(res => {
        proxy.$modal.msgSuccess(res.msg);
        goBack();
    });
  });
}

/** 转办任务 */
function handleTransfer() {
  proxy.$refs["taskFormRef"].validate(valid => {
    if (valid) {
      transferTaskTitle.value = "转办人选择";
      transferTaskOpen.value = true;
    }
  })
}

/** 提交处理转办任务 */
function transferTaskComplete() {
  proxy.$refs["taskFormRef"].validate(valid => {
    if (valid) {
      transferTask(taskForm.value).then(response => {
        proxy.$modal.msgSuccess(response.msg);
        goBack();
      });
      transferTaskTitle.value = "";
      transferTaskOpen.value = false;
    }
  });
}


/** 驳回任务 */
function handleReject() {
  proxy.$refs["taskFormRef"].validate(valid => {
    if (valid) {
      proxy.$confirm("确认驳回任务到上一节点？", "提示", {
        confirmButtonText: "确 认",
        cancelButtonText: "取 消"
      }).then(() => {
        rejectTask(taskForm.value).then(res => {
          proxy.$modal.msgSuccess(res.msg);
          goBack();
        });
      });
    }
  });
}

// 打开退回任务弹窗
function handleReturn() {
  returnFormOpen.value = true;
  returnTaskForm.value = JSON.parse(JSON.stringify(taskForm.value));
  returnTaskForm.value.targetKey = '';
}

// 打开节点选择页面
function handleReturnTaskViewer() {
  proxy.$refs["returnTargetKeyRef"].blur();
  returnViewerOpen.value = true;
  flowXmlAndNode(returnTaskForm.value).then(res => {
    flowNodeData.value = res.data;
  })
}

// 退回节点选择
function returnTaskSelect(checkedNode) {
  returnTaskForm.value.targetKey = checkedNode.key;
  returnTaskForm.value.autoSkip = 'default';
  returnTaskNode.value = [];
  returnTaskNode.value.push(checkedNode);
  returnViewerOpen.value = false;
}


/** 提交退回任务 */
function returnTaskComplete() {
  proxy.$refs["returnTaskFormRef"].validate(valid => {
    if (valid) {
      returnTask(returnTaskForm.value).then(res => {
        if (res.code === 200) {
          proxy.$modal.msgSuccess(res.msg);
          returnFormOpen.value = false;
          returnTaskForm.value = {};
          proxy.$refs["returnTaskFormRef"].resetFields();
          goBack()
        } else {
          proxy.$modal.msgError(res.msg);
        }
      })
    }
  })
}

/** 流程节点按钮 */
function getFlowTaskButton() {
  if (taskForm.value.taskId) {
    flowTaskButton(taskForm.value).then(res => {
      taskButtonList.value = res.data;
    });
  }
}

/**
 * 获取下一任务节点
 */
function nextFLowNode() {
  // 获取下一任务节点
  getNextFlowNode(taskForm.value).then(res => {
    const result = res?.data;
    const delegationStatus = result?.delegationState;
    delegationState.value = delegationStatus;
    // 委托的任务不需要选择任务接收者和传递流程变量信息
    if (delegationStatus !== 'PENDING') {
      const dataList = result?.flowNextList || [];
      nextAssignList.value = dataList.map(data => ({
        nextNodeId: data.nextNodeId,
        nextNodeName: data.nextNodeName,
        dataType: data.dataType,
        currentType: data.type === 'multiInstance'? 'users': data.type,
        flowType: data.type,
        flowParam: data.flowParam,
        selectAssignList: [],
        approval: data?.approval || '',
        userList: data?.userList || [],
        roleList: data?.roleList || [],
        deptList: data?.deptList || [],
        postList: data?.postList || [],
      }));

      nextAssignList.value.forEach(data => {
        // 设置任务审批人/组 ,再次发起申请则不需要选择任务接收人
        if (StrUtil.isNotBlank(data.approval)) {
          // 设置任务审批人/组
          updateSelectAssignList(data, data.currentType);
          taskForm.value.checkedAssignMap[data.nextNodeId] = data.approval;
        }
      })

      // 选择任务接收人或直接提交任务
      if (nextAssignList.value.length > 0) {
        taskSubmitOpen.value = true;
      } else {
        submitTask();
      }
    }
  })
}

// 更新任务审批
function updateSelectAssignList(data, currentType) {
  if (["role", "dept", "post"].includes(currentType)) {
    data.selectAssignList = data[`${currentType}List`].map(item => ({id: item[`${currentType}Id`], name: item[`${currentType}Name`], nodeId: data.nextNodeId}));
  } else if (["assignee", "users"].includes(currentType)) {
    data.selectAssignList = data.userList.map(item => ({id: item.userId, name: item.nickName, nodeId: data.nextNodeId}));
  }
  // 回显审批人
  if ("assignee" === currentType || "dept" === currentType) {
    selectDataMap.value[data.nextNodeId] = data.selectAssignList.map(item => item.id).join(',') || '';
  } else {
    selectDataMap.value[data.nextNodeId] = data.selectAssignList
  }
}


/** 打开任务审批弹窗 */
async function handleComplete() {
  let hasErrorShown = false;
  // 获取表单数据
  const formDataList = await Promise.all(
      vFormRef.value.map(async formRef => {
        try {
          return await formRef.getFormData();
        } catch (error) {
          if (!hasErrorShown) {
            // 多个表单校验时,只弹出一次提示框
            hasErrorShown = true;
            proxy.$modal.msgError("请完善表单信息!");
          }
          throw new Error(`获取表单数据时发生错误: ${error}`);
        }
      })
  );
  const mergedFormData = formDataList.reduce((prev, current) => ({...prev, ...current}), {});

  //  获取表单数据并赋值到流程变量对象中
  taskForm.value.variables = {...mergedFormData};
  // 验证表单数据是否合法
  proxy.$refs["taskFormRef"].validate(valid => {
    if (valid) {
      nextFLowNode();
    }
  })
}

/** 提交用户审批任务 */
async function submitTask() {
  let hasErrorShown = false;
  // 获取表单数据
    const formDataList = await Promise.all(
        vFormRef.value.map(async formRef => {
          try {
            return await formRef.getFormData();
          } catch (error) {
            if (!hasErrorShown) {
              // 多个表单校验时,只弹出一次提示框
              hasErrorShown = true;
              proxy.$modal.msgError("请完善表单信息!");
            }
            throw new Error(`获取表单数据时发生错误: ${error}`);
          }
        })
    );
    const mergedFormData = formDataList.reduce((prev, current) => ({...prev, ...current}), {});

    // 获取表单数据并赋值到表单数据对象中
    taskForm.value.formData = {...mergedFormData};
    //  获取表单数据并赋值到流程变量对象中
    taskForm.value.variables = {...mergedFormData};
    // 如果需要选择任务接收者但是没有选择，则提示错误信息，否则设置流程变量
    for (let i = 0; i < nextAssignList.value.length; i++) {
      const nextAssign = nextAssignList.value[i];
      if (nextAssign.dataType === 'dynamic' && StrUtil.isBlank(taskForm.value.checkedAssignMap[nextAssign.nextNodeId])) {
        proxy.$modal.msgError("请选择" + nextAssign.nextNodeName + "节点任务接收者信息!");
        return;
      }
      // 处理多实例任务,多实例任务的接收者是一个数组
      let checkedValue = taskForm.value.checkedAssignMap[nextAssign.nextNodeId];
      if (nextAssign.flowType && nextAssign.flowType === 'multiInstance') {
        checkedValue = checkedValue.split(',');
      }
      Reflect.set(taskForm.value.variables, nextAssign.flowParam, checkedValue);
    }
    // 验证表单数据是否合法
    proxy.$refs["taskFormRef"].validate(valid => {
      if (valid) {
        // 提交任务
        submitCompleteTask();
      }
    })
}

/** 提交审批任务 */
function submitCompleteTask() {
  completeTask(taskForm.value).then(res => {
    proxy.$modal.msgSuccess(res.msg);
    completeOpen.value = false;
    goBack();
  });
}

// 委托用户
const delegateUserSelect = (selection) => {
  if (selection) {
    taskForm.value.userId = selection.userId.toString();
    taskForm.value.userName = selection.nickName;
  }
}

// 转办用户
const transferUserSelect = (selection) => {
  if (selection) {
    taskForm.value.userId = selection.userId.toString();
    taskForm.value.userName = selection.nickName;
  }
}

// 用户选中数据
const copyUserSelect = (selection) => {
  if (selection) {
    selectCopyDataList.value = JSON.parse(JSON.stringify(selection));
  }
}

// 处理信息选中数据
function handleAssignSelect(selection) {
  if (selection) {
    // 将选中的数据覆盖selectDataList
    selectDataList.value = JSON.parse(JSON.stringify(selection));
  }
}

// 保存抄送选中的数据
function submitCopySelect() {
  // 如果抄送人员选择框打开
  if (copyUserOpen.value) {
    // 将选中的抄送人员列表保存到selectCopyUserList中
    selectCopyUserList.value = JSON.parse(JSON.stringify(selectCopyDataList.value));
    // 将选中的抄送人员的userId保存到taskForm.value.copyUser中
    taskForm.value.copyUser = selectCopyUserList.value.map(item => item.userId);
    // 将选中的抄送人员的userId以逗号分隔保存到taskForm.value.checkedCopyUser中
    taskForm.value.checkedCopyUser = selectCopyUserList.value;
  }
  // 清空选中的数据和关闭抄送人员弹窗
  copyUserOpen.value = false;
}

// 移除抄送人员
function removeCopy(user) {
  proxy.$confirm("确认移除该抄送人员吗？", "提示", {
    confirmButtonText: "确 认",
    cancelButtonText: "取 消"
  }).then(() => {
    const index = selectCopyUserList.value.findIndex(item => item.userId === user.userId);
    if (index !== -1) {
      // 从抄送人员列表中移除该用户
      selectCopyUserList.value.splice(index, 1);
      // 更新任务表单中的抄送人员列表
      taskForm.value.copyUser = selectCopyUserList.value.map(item => item.userId);
      // 更新任务表单中的已选抄送人员
      taskForm.value.checkedCopyUser = selectCopyUserList.value;
    }
  }).catch(() => console.info("操作取消"));
}

// 保存选中的数据
function submitSelect() {
  if (jumpFormOpen.value){
    jumpTaskAssignList.value.forEach(nextAssign => {
      if (nextAssign.nextNodeId === nextNodeId.value) {
        nextAssign.selectAssignList = JSON.parse(JSON.stringify(assignSelect(nextAssign.currentType, nextAssign.nextNodeId, selectDataList.value)));
        const checkedAssign = nextAssign.selectAssignList.map(item => item.id).join(',') || '';
        jumpTaskForm.value.checkedAssignMap[nextAssign.nextNodeId] = checkedAssign;
        if ("assignee" === nextAssign.currentType || "dept" === nextAssign.currentType) {
          selectDataMap.value[nextAssign.nextNodeId] = checkedAssign;
        } else {
          selectDataMap.value[nextAssign.nextNodeId] = nextAssign.selectAssignList
        }
      }
    });
  } else {
    nextAssignList.value.forEach(nextAssign => {
      if (nextAssign.nextNodeId === nextNodeId.value) {
        nextAssign.selectAssignList = JSON.parse(JSON.stringify(assignSelect(nextAssign.currentType, nextAssign.nextNodeId, selectDataList.value)));
        const checkedAssign = nextAssign.selectAssignList.map(item => item.id).join(',') || '';
        taskForm.value.checkedAssignMap[nextAssign.nextNodeId] = checkedAssign;
        if ("assignee" === nextAssign.currentType || "dept" === nextAssign.currentType) {
          selectDataMap.value[nextAssign.nextNodeId] = checkedAssign;
        } else {
          selectDataMap.value[nextAssign.nextNodeId] = nextAssign.selectAssignList
        }
      }
    });
  }
  cancelAssignSelect();
}

// 取消审批人选择
function cancelAssignSelect(){
  completeOpen.value = false;
}

// 移除任务接收人
function removeAssign(assign, nextNodeId) {
  proxy.$confirm("确认移除该任务接收者吗？", "提示", {
    confirmButtonText: "确 认",
    cancelButtonText: "取 消"
  }).then(() => {
    nextAssignList.value.forEach(nextAssign => {
      const index = nextAssign.selectAssignList.findIndex(item => item.id === assign.id && item.nodeId === nextNodeId);
      if (index !== -1) {
        nextAssign.selectAssignList.splice(index, 1);
        const checkedAssign = nextAssign.selectAssignList.map(item => item.id).join(',') || '';
        taskForm.value.checkedAssignMap[nextAssign.nextNodeId] = checkedAssign;
        if ("assignee" === nextAssign.currentType || "dept" === nextAssign.currentType) {
          selectDataMap.value[nextAssign.nextNodeId] = checkedAssign;
        } else {
          selectDataMap.value[nextAssign.nextNodeId] = nextAssign.selectAssignList
        }
      }
    });
  }).catch(() => console.info("操作取消"));
}


/** 动态跳转 */
async function handleDynamicJump() {
  if (delegationState.value === 'PENDING'){
    proxy.$modal.msgError("委托任务不支持动态跳转!");
    return;
  }
  jumpTaskForm.value = JSON.parse(JSON.stringify(taskForm.value));
  jumpTaskForm.value.targetKey = '';
  jumpTaskForm.value.checkedAssignMap = {};
  let hasErrorShown = false;
  // 获取表单数据
  const formDataList = await Promise.all(
      vFormRef.value.map(async formRef => {
        try {
          return await formRef.getFormData();
        } catch (error) {
          if (!hasErrorShown) {
            // 多个表单校验时,只弹出一次提示框
            hasErrorShown = true;
            proxy.$modal.msgError("请完善表单信息!");
          }
          throw new Error(`获取表单数据时发生错误: ${error}`);
        }
      })
  );
  const mergedFormData = formDataList.reduce((prev, current) => ({...prev, ...current}), {});

  // 获取表单数据并赋值到表单数据对象中
  jumpTaskForm.value.formData = {...mergedFormData};
  //  获取表单数据并赋值到流程变量对象中
  jumpTaskForm.value.variables = {...mergedFormData};
  jumpFormOpen.value = true;
}

// 打开节点选择页面
function handleJumpTaskViewer() {
  proxy.$refs.targetKeyRef.blur();
  jumpViewerOpen.value = true;
  flowXmlAndNode(jumpTaskForm.value).then(res => {
    flowNodeData.value = res.data;
    flowNodeData.value.currentKey = jumpTaskForm.value.currentKey;
  })
}

// 动态跳转节点选择
function jumpTaskSelect(checkedNode) {
  jumpTaskNode.value = [];
  jumpTaskForm.value.targetKey = checkedNode.key;
  jumpTaskNode.value.push(checkedNode);
  handleJumpTaskViewerComplete();
}

// 移除任务接收人
function removeJumpTaskAssign(assign, nextNodeId) {
  proxy.$confirm("确认移除该任务接收者吗？", "提示", {
    confirmButtonText: "确 认",
    cancelButtonText: "取 消"
  }).then(() => {
    jumpTaskAssignList.value.forEach(nextAssign => {
      const index = nextAssign.selectAssignList.findIndex(item => item.id === assign.id && item.nodeId === nextNodeId);
      if (index !== -1) {
        nextAssign.selectAssignList.splice(index, 1);
        const checkedAssign = nextAssign.selectAssignList.map(item => item.id).join(',') || '';
        jumpTaskForm.value.checkedAssignMap[nextAssign.nextNodeId] = checkedAssign;
        if ("assignee" === nextAssign.currentType || "dept" === nextAssign.currentType) {
          selectDataMap.value[nextAssign.nextNodeId] = checkedAssign;
        } else {
          selectDataMap.value[nextAssign.nextNodeId] = nextAssign.selectAssignList
        }
      }
    });
  }).catch(() => console.info("操作取消"));
}

function handleJumpTaskViewerComplete() {
  dynamicJumpTask(jumpTaskForm.value).then(res => {
    const result = res?.data;
    const dataList = result?.flowNextList || [];
    jumpTaskAssignList.value = dataList.map(data => ({
      nextNodeId: data.nextNodeId,
      nextNodeName: data.nextNodeName,
      dataType: data.dataType,
      currentType: data.type === 'multiInstance'? 'users': data.type,
      flowType: data.type,
      flowParam: data.flowParam,
      selectAssignList: [],
      approval: data?.approval || '',
      userList: data?.userList || [],
      roleList: data?.roleList || [],
      deptList: data?.deptList || [],
      postList: data?.postList || [],
    }));

    jumpTaskAssignList.value.forEach(data => {
      // 设置任务审批人/组 ,再次发起申请则不需要选择任务接收人
      if (StrUtil.isNotBlank(data.approval)) {
        // 设置任务审批人/组
        updateSelectAssignList(data, data.currentType);
        jumpTaskForm.value.checkedAssignMap[data.nextNodeId] = data.approval;
      }
    })
    jumpViewerOpen.value = false;
  })
}

/** 提交动态跳转任务 */
function jumpTaskComplete() {
  // 如果需要选择任务接收者但是没有选择，则提示错误信息，否则设置流程变量
  for (let i = 0; i < jumpTaskAssignList.value.length; i++) {
    const nextAssign = jumpTaskAssignList.value[i];
    if (nextAssign.dataType === 'dynamic' && StrUtil.isBlank(jumpTaskForm.value.checkedAssignMap[nextAssign.nextNodeId])) {
      proxy.$modal.msgError("请选择跳转目标节点任务接收者信息!");
      return;
    }
    // 处理多实例任务,多实例任务的接收者是一个数组
    let checkedValue = jumpTaskForm.value.checkedAssignMap[nextAssign.nextNodeId];
    if (nextAssign.flowType && nextAssign.flowType === 'multiInstance') {
      checkedValue = checkedValue.split(',');
    }
    Reflect.set(jumpTaskForm.value.variables, nextAssign.flowParam, checkedValue);
  }
  proxy.$refs["jumpTaskFormRef"].validate(valid => {
    if (valid) {
      dynamicJump(jumpTaskForm.value).then(res => {
        if (res.code === 200) {
          proxy.$modal.msgSuccess(res.msg);
          jumpFormOpen.value = false;
          jumpTaskForm.value = {};
          goBack()
        } else {
          proxy.$modal.msgError(res.msg);
        }
      })
    }
  });
}

// 把需要动态调用的方法加入map 中 ,参考地址: https://segmentfault.com/q/1010000042472899?utm_source=sf-similar-question
const eventsMap = {
  handleComplete: () => {
    handleComplete();
  },
  handleDelegate: () => {
    handleDelegate();
  },
  handleTransfer: () => {
    handleTransfer();
  },
  handleReturn: () => {
    handleReturn();
  },
  handleReject: () => {
    handleReject();
  },
  handleStop: () => {
    handleStop();
  },
  handleDynamicJump: () => {
    handleDynamicJump();
  }
};
// 动态绑定操作按钮的点击事件
function handleButtonClick(method) {
  eventsMap[method]()
}

/** 打印预览 */
function handlePrint(){
  printData.value.procDefName = taskForm.value.procDefName;
  printVisible.value = true;
}

/** 选择任务接收 */
function changeNextAssign(item){
  // 设置审批类型组件
  setAssignComponentValue(item.currentType, currentComponent);
  currentType.value = item.currentType;
  nextNodeId.value = item.nextNodeId;
  completeOpen.value = true;
}

// 打开草稿箱
function handleOpenDraft() {
  draftOpen.value = true;
  getDraftList();
}

// 获取草稿箱列表
function getDraftList() {
  loading.value = true;
  queryParams.value.taskId = taskForm.value.taskId
  draftList(queryParams.value).then(res => {
    flowDraftList.value = res.data.records;
    total.value = res.data.total;
    loading.value = false;
  })
}

// 保存草稿
async function saveDraft() {
  let hasErrorShown = false;
  // 获取表单数据
  const formDataList = await Promise.all(
      vFormRef.value.map(async formRef => {
        try {
          return await formRef.getFormData();
        } catch (error) {
          if (!hasErrorShown) {
            // 多个表单校验时,只弹出一次提示框
            hasErrorShown = true;
            proxy.$modal.msgError("请完善表单信息!");
          }
          throw new Error(`获取表单数据时发生错误: ${error}`);
        }
      })
  );
  const mergedFormData = formDataList.reduce((prev, current) => ({...prev, ...current}), {});

  // 获取表单数据并赋值到表单数据对象中
  taskForm.value.formData = {...mergedFormData};
  //  获取表单数据并赋值到流程变量对象中
  taskForm.value.variables = {...mergedFormData};
  saveDraftByTask(taskForm.value).then(() => {
    proxy.$modal.msgSuccess('保存成功');
    goBack();
  })
}

// 使用草稿
function handleUseDraft(row) {
  proxy.$refs.vFormRef.forEach((formRef) => {
    formRef.setFormData(JSON.parse(row.formContent));
  })
  draftOpen.value = false;
}

// 删除草稿
function handleDeleteDraft(row) {
  proxy.$modal.confirm('是否确认删除编号为"' + row.id + '"的草稿？').then(function () {
    return delDraft(row.id);
  }).then(() => {
    getDraftList();
    proxy.$modal.msgSuccess('删除成功');
  }).catch(() => {});
}

/** 关闭当前标签页并返回上个页面 */
function goBack() {
  completeOpen.value = false;
  taskForm.value = {};
  const obj = {path: "/task/todo", query: { t: Date.now()}};
  proxy.$tab.closeOpenPage(obj);
}
</script>

<style lang="scss" scoped>
.test-form {
  margin: 15px auto;
  width: 800px;
  padding: 15px;
}

.clearfix:before,
.clearfix:after {
  display: table;
  content: "";
}

.clearfix:after {
  clear: both
}

.box-card {
  width: 100%;
}

.el-tag + .el-tag {
  margin-left: 10px;
}

.my-label {
  background: #E1F3D8;
}

.el-dialog-div {
  overflow: auto;
}

.button-line {
  margin-top: 5px;
  margin-left: 0;
  margin-right: 5px;
}

.custom-tabs-label .element-icons {
  vertical-align: middle;
}
.custom-tabs-label span {
  vertical-align: middle;
  margin-left: 4px;
}
</style>
